import re
import uuid

from mongoengine import QuerySet, Q

from authorshow.models.models import Author
from expertwords.models import ExpertWords
from fullsearch.models import FullSearch
from orgswords.models import OrgsWords


def select_author(queryset, id=None, name=None, org=None, keywords=None):
    """
    根据条件查询 author
    mongo查询文档：http://docs.mongoengine.org/guide/querying.html
    https://stackoverflow.com/questions/48621541/mongoengine-query-listfield-contains-string-matches

    一些数据处理方法：
    专家学者和机构中英文对照表  -- 原始数据库中添加新字段chiname和chiorgs(导入/不同表间的查询(类似研究领域查询)两种方法时间进行比较);
    研究领域中英文对照表 --  建立新应用(fullsearch),使用keywords进行查询;
    注意到搜索框中包含三个查询：姓名(即name和chiname多字段对应一个搜索框,使用复杂查询)、机构(org和chiorgs)和关键词.

    """
    if not (id or name or org or keywords):
        return None
    result = queryset
    if id is not None:
        result = result.filter(id=id)
    # if name is not None:
    #     result = result(Q(name__icontains=name) | Q(chiname__icontains=name))
    # if h_index is not None:
    #     result = result.filter(h_index=h_index)
    # if pubs is not None:
    #     result = result.filter(pubs__i=pubs)
    # if org is not None:
    #     re_org = '.*' + org + '.*'
    #     result = result(Q(orgs=re.compile(re_org, re.IGNORECASE)) | Q(chiorgs=re.compile(re_org, re.IGNORECASE)))
    # if n_pubs is not None:
    #     result = result.filter(n_pubs=n_pubs)
    # if n_citation is not None:
    #     result = result.filter(n_citation=n_citation)
    # if position is not None:
    #     result = result.filter(position__icontains=position)
    if name is not None:
        querysets = ExpertWords.objects().filter(chicontent__icontains=name)
        name_result = []
        if not querysets:
            result = result.filter(name__icontains=name)
        else:
            for lqueryset in querysets:
                eng_names = lqueryset['engcontent']        # 中文名称对应的英文名称数据库中是一对一情况,若有多个情况,请使用中文、分割
                # 英文名称的正序查询
                res = result.filter(name__icontains=eng_names)
                if res:
                    name_result.extend(res)
                # 英文名称的倒序查询
                strr = str(eng_names).split(' ')     # 英文名称使用空格分隔
                ls = list(strr)
                ls.reverse()
                e_name = " ".join(i for i in ls)
                if e_name == eng_names:
                    continue
                else:
                    res = result.filter(name__icontains=e_name)
                    if res:
                        name_result.extend(res)
            result = Author.objects.filter(pk__in=[x.pk for x in name_result])       # 将列表转化为queryset,由于list不能filter.
    if org is not None and len(org):
        org_querysets = OrgsWords.objects().filter(chicontent__icontains=org)
        org_result = []
        if not org_querysets:
            re_org = '.*' + org + '.*'
            result = result.filter(orgs=re.compile(re_org, re.IGNORECASE))
        else:
            for lqueryset in org_querysets:
                eng_orgs = lqueryset['engcontent']
                re_org = '.*' + eng_orgs + '.*'
                res = result.filter(orgs=re.compile(re_org, re.IGNORECASE))
                if res:
                    org_result.extend(res)
            result = Author.objects.filter(pk__in=[x.pk for x in org_result])
    if keywords is not None and len(keywords):
        querysets = FullSearch.objects().filter(chicontent__icontains=keywords)
        tag_result = []
        if not querysets:
            result = result.filter(tags__t__icontains=keywords)
            return result
        else:
            for lqueryset in querysets:
                tags = lqueryset["engcontent"].split("、")
                for tag in tags:
                    res = result.filter(tags__t__icontains=tag)
                    if res:
                        tag_result.extend(res)        # 注意: python列表append和extend区别
        result = Author.objects.filter(pk__in=[x.pk for x in tag_result])
    return result

def select_paper(queryset, id=None, title=None, authors=None, venue=None, keywords=None, abstract=None):
    """
    查询 paper
    :return:
    """
    if id is not None:
        result = queryset.filter(id=id)
    elif (title is not None) and (authors is not None) and (venue is not None) and (keywords is not None) and (
            abstract is not None):
        result = queryset.filter(title=title, authors=authors, venue=venue, keywords=keywords, abstract=abstract)
    elif title is not None:
        result = queryset.filter(title__contains=title)
    else:
        return None
    return result


def create_coll_id(queryset: QuerySet):
    """生成唯一的uuid"""
    id = uuid.uuid1()
    while queryset.filter(id=id).first() is not None:
        id = uuid.uuid1()
    return str(id)


def select_research(queryset, id=None, word=None):
    '''科研热点按照keywords和标题搜索情况,注意这两个字段是在同一个搜索框中进行搜索'''
    if not(id or word):
        return None
    result = queryset
    if id is not None:
        result = result.filter(id=id)
    if word is not None:
        re_keywords = '.*' + word + '.*'
        result = result(Q(title__icontains=word) | Q(keywords=re.compile(re_keywords, re.IGNORECASE)))
    return result


def select_research_org(queryset, id=None, org=None, info=None):
    '''科研热点按照authors.org搜索情况'''
    if not (id or org or info):
        return None
    result = queryset
    if id is not None:
        result = result.filter(id=id)
    if org is not None:
        re_org = '.*' + org + '.*'
        result = result.filter(orgs=re.compile(re_org, re.IGNORECASE))
    if info is not None:
        querysets = FullSearch.objects().filter(chicontent__icontains=info)
        if not querysets:
            result = result.filter(tags__t__icontains=info)
            return result
        else:
            tag_result = []
            for lqueryset in querysets:
                tags = lqueryset["engcontent"].split("、")
                for tag in tags:
                    res = result.filter(tags__t__icontains=tag)
                    if res:
                        tag_result.extend(res)        # 注意: python列表append和extend区别
            return tag_result
    return result


def select_research_author(queryset, id=None, name=None, info=None):
    """科研热点按照单个author搜索情况"""
    if not (id or name or info):
        return None
    result = queryset
    if id is not None:
        result = result.filter(id=id)
    if name is not None:
        # 作者名称使用英文搜索
        # re_name = '.*' + name + '.*'
        # result = result.filter(name=re.compile(re_name, re.IGNORECASE))
        result = result.filter(name__icontains=name)
    if info is not None:
        querysets = FullSearch.objects().filter(chicontent__icontains=info)
        if not querysets:
            result = result.filter(tags__t__icontains=info)
            return result
        else:
            tag_result = []
            for lqueryset in querysets:
                tags = lqueryset["engcontent"].split("、")
                for tag in tags:
                    res = result.filter(tags__t__icontains=tag)
                    if res:
                        tag_result.extend(res)        # 注意: python列表append和extend区别
            return tag_result
    return result
